/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tcloudclient.actionManager;

import api.Rights.RightsEnum;
import api.action.ActionInterface;
import api.action.ActionPackageServer;
import api.action.actionImplementations.server.*;
import api.action.crates.Server.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import tcloudclient.contex.Context;
import tcloudclient.fileSystem.FileNode;
import tcloudclient.fileSystem.FileStatusEnum;

/**
 *
 * @author Tomas
 */
public class ActionBuilder {

    private FileNode rootNode;

    public ActionBuilder(FileNode rootNode) {

        this.rootNode = rootNode;
    }

    public ActionPackageServer generateActions() {
        List<ActionInterface> generateActions = generateActions(rootNode);

        ActionPackageServer acPackage = new ActionPackageServer(generateActions, Context.getInstance().getApplicationSettings().getAccHeaderVetsion(), Context.getInstance().getApplicationSettings().getUserId());
        return acPackage;
    }

    private List<ActionInterface> generateActions(FileNode root) {
        List<ActionInterface> actions = new ArrayList<>();
        List<FileNode> files = new ArrayList<>();
        files.addAll(root.getChilds());
        while (!files.isEmpty()) {
            FileNode file = files.remove(0);
            if (file.getStatus() != FileStatusEnum.NOMODIFY) {
                switch (file.getStatus()) {
                    case NEW:
                        createNewAction(file, actions);
                        break;
                    case RENAME:
                    case MODIFY:
                        createModifyAction(file, actions);
                        break;
                    case DELETE:
                        createDeleteAction(file, actions);
                        break;
                }
            }
            files.addAll(file.getChilds());
        }
        return actions;
    }

    private void createNewAction(FileNode file, List<ActionInterface> actions) {
        String path = file.getFile().getAbsolutePath().substring(rootNode.getFile().getAbsolutePath().length() + 1);
        String[] pathSplit = path.split(Pattern.quote(File.separator));
        ActionInterface action;
        if (!file.getFile().isDirectory()) {
            NewFileCrate crate = new NewFileCrate(pathSplit, readBytesFromFile(file));
            action = new NewFileAction(crate);
        } else {
            NewFolderCrate crate = new NewFolderCrate(pathSplit);
            action = new NewFolderAction(crate);
        }
        actions.add(action);
    }

    private void createModifyAction(FileNode file, List<ActionInterface> actions) {
        if (file.getRights() == RightsEnum.WRITE || file.getRights() == RightsEnum.DELETE) {
            ActionInterface action;
            String path = file.getFile().getAbsolutePath().substring(rootNode.getFile().getAbsolutePath().length() + 1);
            String[] pathSplit = path.split(Pattern.quote(File.separator));
            String oldName = null;
            if (file.getStatus() == FileStatusEnum.RENAME) {
                oldName = pathSplit[pathSplit.length - 1];
                pathSplit[pathSplit.length - 1] = file.getOldName();
            }
            if (file.getFile().isDirectory()) {
                action = new UpdateFolderAction(new UpdateFolderCrate(pathSplit, oldName, file.getVersion()));
            } else {
                action = new UpdateFileAction(new UpdateFileCrate(pathSplit, oldName, file.getVersion(), readBytesFromFile(file)));
            }
            actions.add(action);
        }
    }

    private void createDeleteAction(FileNode file, List<ActionInterface> actions) {
        if (file.getRights() == RightsEnum.DELETE) {
            String path = file.getFile().getAbsolutePath().substring(rootNode.getFile().getAbsolutePath().length() + 1);
            String[] pathSplit = path.split(Pattern.quote(File.separator));
            ActionInterface action;
            if (file.isLeaf()) {
                action = new DeleteFileAction(new DeleteFileCrate(pathSplit, file.getVersion()));
            } else {
                action = new DeleteFolderAction(new DeleteFolderCrate(pathSplit, file.getVersion()));
            }
            actions.add(action);
        }
    }

    private byte[] readBytesFromFile(FileNode file) {
        FileInputStream fin = null;
        byte fileContent[] = null;
        try {
            fin = new FileInputStream(file.getFile());
            fileContent = new byte[(int) file.getFile().length()];
            fin.read(fileContent);
        } catch (IOException ex) {
            Logger.getLogger(ActionBuilder.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                fin.close();
            } catch (IOException ex) {
                Logger.getLogger(ActionBuilder.class.getName()).log(Level.SEVERE, null, ex);
            }
            return fileContent;
        }
    }
}
